package com.blue.gateway.paycore.wxpay.notify;

import com.blue.gateway.config.BaseChannelConfig;
import com.blue.gateway.annotation.Channel;
import com.blue.gateway.common.Request;
import com.blue.gateway.common.request.PayNotifyRequest;
import com.blue.gateway.common.response.PayResponse;
import com.blue.gateway.config.WxConfig;
import com.blue.gateway.paycore.AbstractBaseChannelService;
import com.blue.gateway.paycore.wxpay.WxPayConstants;
import com.blue.gateway.dto.Result;
import com.blue.gateway.dto.ResultWrapper;
import com.blue.gateway.enums.PayChannelEnum;
import com.blue.gateway.enums.ResultCodeEnum;
import com.blue.gateway.enums.ServiceChannelEnum;
import com.blue.gateway.utils.XmlUtil;
import com.blue.gateway.utils.sign.WxPaySignature;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Map;

/**
 * @author xiaoyiming
 * @date 2020/5/4 21:43
 * @depiction 支付回调
 */
@Slf4j
@Channel(PayChannel = PayChannelEnum.WX, ServiceChannel = ServiceChannelEnum.PAY_NOTIFY)
public class WxPayNotifyService extends AbstractBaseChannelService {

    @Autowired
    private WxConfig wxConfig;

    @Override
    public Result validate(Request request) {
        PayNotifyRequest payNotifyRequest = (PayNotifyRequest) request;
        if (StringUtils.isBlank(payNotifyRequest.getNotifyData())) {
            return ResultWrapper.fail(ResultCodeEnum.PARAM_ILLEGAL);
        }
        return ResultWrapper.success();
    }

    @Override
    public BaseChannelConfig getConfig(Request request) {
        return wxConfig;
    }

    @Override
    public String generateParams(Request request, BaseChannelConfig channelConfig) {
        PayNotifyRequest payNotifyRequest = (PayNotifyRequest) request;
        return payNotifyRequest.getNotifyData();
    }


    @Override
    public String execute(String requestParams, BaseChannelConfig channelConfig) {
        WxConfig wxConfig = (WxConfig) channelConfig;
        //签名校验
        if (!WxPaySignature.verify(XmlUtil.toMap(requestParams), wxConfig.getParterKey())) {
            log.error("【微信支付异步通知】签名验证失败, response={}", requestParams);
            throw new RuntimeException("【微信支付异步通知】签名验证失败");
        }

        return requestParams;
    }

    /**
     * <xml>
     * <appid><![CDATA[wxd898fcb01713c658]]></appid>\n
     * <bank_type><![CDATA[OTHERS]]></bank_type>\n
     * <cash_fee><![CDATA[2]]></cash_fee>\n
     * <fee_type><![CDATA[CNY]]></fee_type>\n
     * <is_subscribe><![CDATA[Y]]></is_subscribe>\n
     * <mch_id><![CDATA[1483469312]]></mch_id>\n
     * <nonce_str><![CDATA[en8ATCCTwQ1NaWLL]]></nonce_str>\n
     * <openid><![CDATA[oTgZpwcqJrSlwSeYPoXaOrohFgXk]]></openid>\n
     * <out_trade_no><![CDATA[1235647879511320464]]></out_trade_no>\n
     * <result_code><![CDATA[SUCCESS]]></result_code>\n
     * <return_code><![CDATA[SUCCESS]]></return_code>\n
     * <sign><![CDATA[C4AA8275CF8491CD4DB6E8D1EF2A6FD8]]></sign>\n
     * <time_end><![CDATA[20200505181701]]></time_end>\n
     * <total_fee>2</total_fee>\n
     * <trade_type><![CDATA[NATIVE]]></trade_type>\n
     * <transaction_id><![CDATA[4200000567202005054899678515]]></transaction_id>\n
     * </xml>
     */
    @Override
    public Result analysisResult(String executeResult) {
        Map<String, String> result = XmlUtil.toMap(executeResult);
        PayResponse payResponse = new PayResponse();
        payResponse.setData(executeResult);

        if (WxPayConstants.SUCCESS.equals(result.get("return_code"))) {
            payResponse.setTradeNo(result.get("transaction_id"));
            payResponse.setMsg(result.get("return_msg"));

            String returnResult =
                    "<xml>" +
                            "<return_code><![CDATA[SUCCESS]]></return_code>" +
                            "<return_msg><![CDATA[OK]]></return_msg>" +
                            "</xml>";
            payResponse.setPayUrl(returnResult);

            return ResultWrapper.success(payResponse);
        }


        return ResultWrapper.fail(payResponse);
    }
}
